package com.core.result;

import cn.hutool.core.util.StrUtil;
import com.core.enums.ResultCodeEnums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * 通用统一返回结果封装类
 *
 * @param <T> 响应数据类型
 * 用于 API 接口统一结构返回，包含状态码、提示信息和实际数据。
 * @author hc
 * @CreateTime 2025/7/29 14:36
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class CmdResult<T> {

    /**
     * 状态码，约定：200 表示成功，其他为失败或异常
     */
    private String code;

    /**
     * 提示信息（如：成功、错误详情等）
     */
    private String message;

    /**
     * 响应数据主体
     */
    private T data;

    // -------------------- 成功返回 --------------------

    /**
     * 成功（无数据）
     */
    public static <T> CmdResult<T> ok() {
        return new CmdResult<>(ResultCodeEnums.SUCCESS.getCode(),ResultCodeEnums.SUCCESS.getMessage(), null);
    }

    /**
     * 成功（包含数据）
     */
    public static <T> CmdResult<T> ok(T data) {
        return new CmdResult<>(ResultCodeEnums.SUCCESS.getCode(), ResultCodeEnums.SUCCESS.getMessage(), data);
    }

    /**
     * 成功（自定义提示 + 数据）
     */
    public static <T> CmdResult<T> ok(String message, T data) {
        return new CmdResult<>(ResultCodeEnums.SUCCESS.getCode(), message, data);
    }

    // -------------------- 错误返回 --------------------

    /**
     * 默认错误（500）
     */
    public static CmdResult<?> error() {
        return new CmdResult<>(ResultCodeEnums.INTERNAL_SERVER_ERROR.getCode(), ResultCodeEnums.INTERNAL_SERVER_ERROR.getMessage(), null);
    }

    /**
     * 自定义错误信息（默认 500 状态码）
     */
    public static CmdResult<?> error(String message) {
        return new CmdResult<>(ResultCodeEnums.INTERNAL_SERVER_ERROR.getCode(), message, null);
    }

    /**
     * 自定义错误码与信息（无数据）
     */
    public static <T> CmdResult<T> error(String code, String message) {
        return new CmdResult<>(code, message, null);
    }

    /**
     * 自定义错误码与信息（带数据）
     */
    public static <T> CmdResult<T> error(String code, String message, T data) {
        return new CmdResult<>(code, message, data);
    }

    // -------------------- 枚举支持：ResultCodeEnums --------------------

    /**
     * 使用 ResultCodeEnums 构建成功返回（无数据）
     */
    public static CmdResult<?> of(ResultCodeEnums codeEnum) {
        return new CmdResult<>(codeEnum.getCode(), codeEnum.getMessage(), null);
    }

    /**
     * 使用 ResultCodeEnums 构建成功返回（带数据）
     */
    public static <T> CmdResult<T> of(ResultCodeEnums codeEnum, T data) {
        return new CmdResult<>(codeEnum.getCode(), codeEnum.getMessage(), data);
    }

    /**
     * 判断是否为成功（code == 200）
     */
    public boolean isSuccess() {
        return StrUtil.equals(code, ResultCodeEnums.SUCCESS.getCode());
    }

    /**
     * 判断是否为失败
     */
    public boolean isError() {
        return !isSuccess();
    }

}
